home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-22 | 91.1 KB | 2,978 lines | [TEXT/MPS ] |
- /*
- File: DragDrp.cpp
-
- Contains: Implementation of ODDragAndDrop
-
- Owned by: Vincent Lo
-
- Copyright: © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <8> 4/16/96 DH Fixed InWindow to ignore a null container.
- <7> 4/9/96 DH 1308248: 1.0.2 Drag of no-part to trash
- rejected. Used string resource for no-part
- category instead of hard-coding it. Also
- made filename of file in Trash when you
- drop Nopart into the trash not be garbled.
- <6> 4/8/96 DH 1338112: 1.0.2? Drag Hiliting Problems
- <4> 3/29/96 DM 1296171: delay fatal Bento container errors
- when inside drag manager
- <3> 3/15/96 VL 1302780: Use GetFacetUnderPointForDrag
- instead of GetFacetUnderPoint so that we
- can drop within selection.
- <2> 3/15/96 DH 287259 - 1.0.2 Don't get back what I put in
- the scrapbook. Now writes out a memory
- container to applications that it reloads
- if it is found from Drag and Drop. Also
- compatible with Clipboard container type.
- 1293781 - 1.0.2 DragWithin called out of
- order. Fixed ODDragAndDropInWindow so that
- it doesn't call DragLeave on the Containing
- part unless the embedded part returns True
- from DragEnter.
- <84> 10/22/95 TÇ 1291419 GM: File type set incorrectly for
- Old Mac data dragged to Finder from
- OpenDoc.
- <83> 10/13/95 TÇ 1284461 GM: Parts that are created in a
- document should not automatically be given
- names
- <82> 10/8/95 TJ Fixes Recomended by Refball
- <81> 10/4/95 jpa Added missing ODVolatiles [1285799]
- <80> 10/4/95 VL 1287367: Added code in MySendDataProc to
- check whether we are dragging to the trash.
- 1286642: Removed bogus kODPromiseFlavor.
- Check for nil handle or invalid fsspec in
- GetDropFSSpec. Added gIsResolvingPromise to
- ensure that we know when we are fulfulling
- a promise.
- <79> 10/3/95 TJ Changes done by RefBall Team
- <78> 9/13/95 VL Removed leftover debugstr from last
- checkin.
- <77> 9/13/95 VL 1283523: Dragging parts between Documents &
- Finder needs to reflect new behavior. Added
- a lot of apple event handlers.
- <76> 9/8/95 VL 1275241, 1283463: Use
- ODPlatformDragReference everywhere.
- <75> 9/8/95 TÇ 1281096 FB2:Many constants in ODTypesB
- without kOD prefix!
- <74> 9/6/95 VL 1255735, 1274572: SetStationery in
- SetFinderInfo. Set up finderFile in
- EnterHandler to get the finder file info.
- Removed CreateNewFile. Changed
- MakeUniqueFilename to use resources for
- localization and to follow the HI
- guidelines.
- <73> 9/1/95 CC 1273646, 1279220: CloneIntoFile: Use
- kODCloneToFile.
- <72> 8/30/95 EL 1279832: Storage THROW_IF_NULL problems.
- <71> 8/29/95 VL 1276864, 1276541: Change result to
- kODDropCopy if the original clone kind is
- copy.
- <70> 8/29/95 jpa Univ Hdrs 2.1 fix [1279173]
- <69> 8/22/95 VL 1265957, 1278381: If a part returns
- kODFalse from DragEnter and DragWithin, try
- the containing facet.
- <68> 8/22/95 eeh 1276821:
- kOpenDocShellSignature->kODShellSignature
- <67> 8/21/95 VL 1274367: Removed WARN statement in
- CopyFromDragItemInChunks.
- <66> 8/17/95 CC 1199356: Turn off paste as attribute on
- drop into background window.
- <65> 8/17/95 CC 1277777: MyRecieveDropHandler: Set drop
- result to kODDropFail when an exception is
- caught.
- Use ODVolatile(targetPart) or suffer
- refcount error on failure.
- <64> 8/16/95 jpa Updated call to ODGetIconFamilyProp
- [1212507]
- <63> 8/16/95 VL 1244813: removed ASLMBUILD.
- <62> 8/12/95 TÇ 1276812 Need to use TempObjs and TempRefs
- for exception safety and to avoid TRY
- blocks, 1276807 Opt./Bug: use StdTypIO
- routines for portable streaming & smaller
- footprint
- <61> 8/3/95 RR #1257260: Collapse B classes. Remove
- somInit methods. Don't call IsInitialized
- or SubclassResponsibility
- <60> 7/21/95 VL 1270320: Dispose isoType returned from
- GetISOTypeFromPlatformType.
- <59> 6/28/95 VL 1190962, 1252228: Added code for creating
- non-OD document.
- <58> 6/26/95 VL 1262622: Call InitDateInfo in SetFinderInfo
- to make sure that the modDate and
- creationDate are set up.
- <57> 6/25/95 VL 1255300: Added code for roundtrip D&D with
- Finder (SetIconFamily and SetFinderInfo).
- <56> 6/20/95 VL 1161434, 1194603: Reordered
- AddDragItemFlavor to work around
- interaction problems with Finder.
- <55> 6/2/95 CC 1255476: MyReceiveDropHandler, EnterWindow,
- InWindow: Release part acquired via
- ODFrame::AquirePart.
- 1255474: AcquireStorageUnitOSType restored
- to GetStorageUnitOSType.
- 1255474: AcquireSourceFrame restored to
- GetSourceFrame.
- 1255474: AcquireSourcePart restored to
- GetSourcePart.
- <54> 5/26/95 VL 1251403: Multithreading naming support.
- <53> 5/25/95 jpa List.h --> LinkList.h [1253324]
- <52> 5/18/95 CC 1250280: ShowPasteAsDialog throws on
- invalid null arguments. 1238898: Add
- destFrame argument to BeginClone call.
- <51> 5/17/95 RR #1250135/1250137/1250143 Getters increment
- refcount
- <50> 5/11/95 DM #1246524, #1246529:
- ValueNameSpaceGetEntry() must pass through
- the value allocated.
- <49> 5/5/95 CC 1246586: CloneIntoFile: Clone content frame
- into document draft and create root frame
- list property.
- <49> 5/5/95 CC 1246586: CloneIntoFile: Clone content frame
- into document draft and create root frame
- list property.
- <48> 5/2/95 CC 1207493: MyReceiveDropHandler: Call
- SetDestFacet BEFORE targetFacet->Drop() so
- CMDraft can get the target facet.
- <47> 5/2/95 VL 1230557: Remove kODPropMouseDownOffset.
- <46> 4/15/95 VL 1240014: Added TRY-CATCH blocks and turned
- off debug statements.
- <45> 4/14/95 VL Temporarily turned on debug printf.
- <44> 4/10/95 VL 1196870: Preserved HasLeftSourceFrame
- behavior.
- <43> 3/31/95 VL 1228756: Made dragdrop work with
- non-persistent frame.
- <42> 3/23/95 VL 1228275: ASSERT for null ODByteArray.
- <41> 3/22/95 CC 1230322: Changed parameter to
- ShowPasteAsDialog().
- <40> 3/10/95 VL 1227218: Get rid of system heap.
- <39> 2/28/95 VL 1194656: Check for existence before adding
- property or value.
- <38> 2/7/95 CC 1211295: Pass isMove parameter to
- ShowPasteAsDialog.
- <37> 2/2/95 CC 1153802: Added DragItemHasFlavor().
- CopyFromDragItemInChunks() writese data at
- current offset, instead of replacing the
- entire value.
- Automatically generate 'stxt' from
- 'styl'+'TEXT'; generate 'styl' from 'stxt'.
- <36> 2/2/95 CG #1195019: ValueNameSpace entries are now
- copied in and out instead of pointers being
- passed around.
- <35> 2/1/95 VL 1209010: Implemented more err checking.
- <34> 1/26/95 VL #???: Use updated Storage Unit Ref API.
- <33> 1/23/95 CG #1195019: ValueNameSpace methods now take
- ODByteArray parameter instead of ODPtr.
- <32> 1/9/95 VL 1195012, 1196957: StartDrag now takes
- ODByteArray. Drag Attributes now returns
- whether the nature of the drop.
- <31> 12/20/94 VL 1195012: Make Storage calls be
- marshallable.
- <30> 12/13/94 VL 1203627,1200603,1203451,1198037,1194537,119
- 4755,1186815: Bug fixes.
- <29> 11/14/94 VL 1194890: Enabled fulfulling multiple
- promises.
- <28> 10/19/94 VL 1162335: Now D&D adds a special value if
- the dragged item is a non-OD file.
- <27> 10/12/94 RA Fix uninitilized variable.
- <26> 10/4/94 VL 1162335: Added implementation on handling
- non-OD files. Also chewed up MouseUp event
- after drop.
- <25> 9/29/94 RA 1189812: Mods for 68K build.
- <24> 9/28/94 JBS (for VL) 1162335: fixed unitialized
- dataSize
- <23> 9/27/94 VL 1142048: Do not call DragLeave if there is
- a Drop.
- <22> 9/26/94 VL 1162335: Enabled dragging from non-od docs.
- <21> 9/23/94 VL 1155224: Drag to Finder names the drop
- correctly. Also, enable dragging to trash.
- <20> 9/23/94 VL 1184272: ContainerID is a sequence of
- octets.
- <19> 9/23/94 CC 1187509 - Implemented ShowPasteAsDialog().
- <18> 9/15/94 VL 1184871: Fixed SendDataProc to handle
- promises.
- <17> 8/26/94 VL 1183174: Use updated cloning APIs.
- <16> 8/17/94 jpa (forgot bug# for <15>, which is 1181530)
- <15> 8/17/94 jpa ODDragAndDropsomUninit was calling parent's
- somUninit twice!!
- <14> 8/15/94 TÇ #1180922 Removed most obsolete types from
- StdTypes.idl
- <13> 8/11/94 eeh bug 1180486: MySendDataProc needs to call
- SetDropResult
- <12> 8/10/94 JBS 1179919: coordinate system bias changes
- <11> 8/9/94 VL 1176710: Dragging an alias to OpenDoc
- document now works. 1179857: DragEnter and
- DragWithin return ODBoolean.
- <10> 8/3/94 VL 1153123: Storage to ODStor.
- <9> 8/2/94 CC #1178169 - ShowPasteAsDialog() takes
- ODFacet* instead of ODFrame*.
- <8> 7/29/94 VL THROW if D&D not installed.
- <7> 7/27/94 CC Touched to accompany .idl checkin.
- <6> 7/26/94 VL Reduced dependency on Bento and got rid of
- DragAndDropStorageUnit.
- <5> 7/21/94 VL Made it run in SOM.
- <4> 7/7/94 CC Removed constants now defined by
- ODTypesB.idl.
- <3> 7/5/94 CC MySendDataProc: Added blocks to case stmts
- that were declaring locals at the scope of
- the switch stmt.
- <2> 6/30/94 jpa Fixed some illegal implicit casts from
- void*.
- <1> 6/28/94 VL first checked in
-
- To Do:
- In Progress:
- */
-
- #ifndef _ALTPOINT_
- #include "AltPoint.h" // Use C++ savvy ODPPoint and ODPRect
- #endif
-
- #define ODDragAndDrop_Class_Source
- #define VARIABLE_MACROS
- #include <DragDrp.xih>
-
- #ifndef SOM_ODDragItemIterator_xh
- #include <DgItmIt.xh>
- #endif
-
- #ifndef _DRAGPRIV_
- #include <DragPriv.h>
- #endif
-
- #ifndef _STORRSRC_
- #include <StorRsrc.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef SOM_ODContainer_xh
- #include <ODCtr.xh>
- #endif
-
- #ifndef SOM_ODDocument_xh
- #include <Document.xh>
- #endif
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- #ifndef SOM_ODWindow_xh
- #include <Window.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef SOM_ODPart_xh
- #include <Part.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- #ifndef SOM_ODTranslation_xh
- #include <Translt.xh>
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- #ifndef _ODNew_
- #include "ODNew.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _LINKLIST_
- #include "LinkList.h"
- #endif
-
- #ifndef SOM_ODStorageUnitView_xh
- #include <SUView.xh>
- #endif
-
- #ifndef _STORDEF_
- #include "StorDef.h"
- #endif
-
- #ifndef SOM_CMStorageUnit_xh
- #include <CMSU.xh>
- #endif
-
- #ifndef _PLFMFILE_
- #include <PlfmFile.h>
- #endif
-
- #ifndef _CONSTDEF_
- #include "ConstDef.h"
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdDefs_defined
- #include "StdDefs.xh"
- #endif
-
- #ifndef _LINKDLGS_
- #include "LinkDlgs.h"
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __SCRIPT__
- #include <Script.h>
- #endif
-
- #ifndef __PACKAGES__
- #include <Packages.h>
- #endif
-
- #ifndef __APPLEEVENTS__
- #include <AppleEvents.h>
- #endif
-
- #ifndef _ISOSTR_
- #include <ISOStr.h>
- #endif
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef _BARRAY_
- #include <BArray.h>
- #endif
-
- #ifndef SOM_ODNameSpaceManager_xh
- #include <NmSpcMg.xh>
- #endif
-
- #ifndef SOM_ODValueNameSpace_xh
- #include <ValueNS.xh>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _STORUTIL_
- #include "StorUtil.h"
- #endif
-
- #include <string.h>
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _NMSPCUTL_
- #include <NmSpcUtl.h>
- #endif
-
- #ifndef _STDTYPIO_
- #include <StdTypIO.h>
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- #ifndef _INFOUTIL_
- #include <InfoUtil.h>
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __FINDER__
- #include <Finder.h>
- #endif
-
- #ifndef _POUTILS_
- #include <POUtils.h>
- #endif
-
- #ifndef _OPENHASH_
- #include <OpenHash.h>
- #endif
-
- #ifndef _ITEXT_
- #include <IText.h>
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _DRGDPDEF_
- #include "DrgDpDef.h"
- #endif
-
- #ifndef __DIALOGS__
- #include <Dialogs.h>
- #endif
-
- static FSSpec gTmpFileFSSpec;
- static FSSpec gTargetFSSpec;
- static boolean gIsResolvingPromise = kODFalse;
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- #define kODUserPromiseFlavor 0x66696c65 // 'file'
- //#define kODBentoFlavor 0x626E746F // 'bnto'
- // The Bento container flavor was changed to odcn so we have compatibility with
- // the clipboard.
- #define kODBentoFlavor 0x6F64636E // 'odcn'
- #define kODPromiseFlavor 0x70726D73 // 'prms'
- #define kODPromiseDesc 0x70726D73 // 'prms'
- #define kODScrapTypestyl 0x7374796c // 'styl'
- #define kODScrapTypestxt 0x73747874 // 'stxt'
- #define kODScrapTypeTEXT 0x54455854 // 'TEXT'
-
- #define kODDropHasLeftSourceFrameMask ~kODDropIsInSourceFrame
- #define kODDragHasLeftSourcePartMask ~(kODDropIsInSourceFrame | kODDropIsInSourcePart)
-
- // #define kODDestinationFileSpec 'dfss'
- // #define kODSourceFileSpec 'sfss'
- // #define kODPreReplaceFileEventID 'prfl'
- // const FourCharCode kODReplaceFileEventID = 'rfl ';
- // #define kODSession 'sess'
-
- #define kODDestinationFileSpec 'DFSS'
- #define kODSourceFileSpec 'SFSS'
- #define kODReplaceFileEventID 'RFL '
- #define kODSession 'SESS'
-
- const ODULong kODInitialNumEntries = 8;
-
- #if ODDebug
- // #define ODDebug_DragAndDrop 1
- #endif
-
- //==============================================================================
- // Scalar Types
- //==============================================================================
-
- typedef struct {
- ODPart *sourcePart;
- ODStorageUnitView *destSUView;
- } ODPromiseDesc;
-
- #define IsOpenDocDocument(osType) ((osType != 'APPL') && (osType != 'shlb'))
- #define SetPasteAsAttribute(self, ev, m) do {if ((m & cmdKey) && IsFrontProcess()) self->SetAttributes(ev, self->GetAttributes(ev) | kODDropIsPasteAs);} while (0)
-
- //==============================================================================
- // Prototyping
- //==============================================================================
-
- extern ODBoolean gODBentoFatalErrorHasOccurred; // SessHdr.cpp
- extern ODBoolean gODDelayBentoFatalError; // SessHdr.cpp
- extern ODBoolean gODSuppressBentoFatalError; // SessHdr.cpp
- extern void ODBentoFatalError(); // SessHdr.cpp
-
- static pascal OSErr MyDragTrackingHandler(
- short message,
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag);
-
- static pascal OSErr MyReceiveDropHandler(
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag);
-
- static pascal OSErr MySendDataProc(
- FlavorType theType,
- void* refCon,
- ItemReference theItem,
- ODPlatformDragReference theDrag);
-
- static OSErr ODPascal ReplaceFileAEHandler(
- const AppleEvent* replaceFileEvent,
- AppleEvent* reply,
- long refCon);
-
- static void RespecifyToTempFolder(PlatformFile* file);
- static OSErr CreateReplaceFileEvent(Environment* ev, AppleEvent* replaceFileEvent, ODSession* session, ProcessSerialNumber* psn);
- static OSErr SetupReplaceFileEvent(Environment* ev, AppleEvent* replaceFileEvent, FSSpec* sourceFileSpec, FSSpec* destFileSpec);
- static OSErr SendReplaceFileEvent(AppleEvent* replaceFileEvent, ProcessSerialNumber* psn);
- static OSErr DisposeReplaceFileEvent(AppleEvent* replaceFileEvent);
- static ODBoolean DragItemHasFlavor(ODPlatformDragReference theDrag, ItemReference itemID, OSType theType);
- static OSErr CloneIntoFile(Environment* ev, ODDragItem* theDragItem, FSSpec dropFSSpec);
- static void CloneIntoFlavor(Environment* ev, ODDragAndDrop* dad, ODDragItem* theDragItem,
- ODPlatformDragReference theDrag, ItemReference theItem, FlavorType theType,
- FSSpec dropFSSpec);
- static boolean MakeUniqueFilename( Environment *ev, ODSession* session, ODStorageUnit *su, FSSpec *spec );
- static OSType GetStorageUnitOSType( Environment *ev, ODStorageUnit *su );
- static OSErr CopyToDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem);
- static OSErr CopyFromDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODStorageUnitView* destSUView);
-
- static OSErr CopyMemContainerToDragItemInChunks(Environment* ev,
- ODSession* theSession,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem);
-
- static ODHandle CloneToTempMemContainer( Environment* ev, ODMemDragItem* tempDItem, ODSession* theSession );
- static void SetFinderInfo(Environment* ev, ODStorageUnit* su, PlatformFile* file);
- static void SetIconFamily(Environment* ev, ODStorageUnit* fromSU, PlatformFile* file);
- static OSErr GetDropFSSpec(ODPlatformDragReference theDrag, FSSpec& dropFSSpec);
- static boolean IsTrashFolder(FSSpec dropFSSpec);
- static boolean IsFrontProcess();
-
- #ifdef ODDebug_DragAndDrop
-
- #ifndef SOM_ODStorageUnitCursor_xh
- #include <SUCursor.xh>
- #endif
-
- void PrintDragReference(ODPlatformDragReference dragRef, char* header);
- void PrintStorageUnit(Environment* ev, ODStorageUnit* su, char* header);
- #endif
-
- #pragma segment ODDragAndDrop
-
- #include "DragDrpB.cpp" // Platform-independent methods, if any
-
-
- SOM_Scope ODBoolean SOMLINK ODDragAndDropShowPasteAsDialog(ODDragAndDrop *somSelf, Environment *ev,
- ODBoolean canPasteLink,
- ODPasteAsMergeSetting mergeSetting,
- ODFacet* facet,
- ODTypeToken viewType,
- ODStorageUnit* contentSU,
- ODPasteAsResult* result)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropShowPasteAsDialog");
-
- SOM_CATCH return kODFalse;
-
- THROW_IF_NULL(facet, kODErrNullFacetInput);
- THROW_IF_NULL(contentSU, kODErrIllegalNullStorageUnitInput);
- THROW_IF_NULL(result, kODErrNullPasteAsResultInput);
-
- ODBoolean returnValue = ShowPasteAsDialog(
- canPasteLink,
- mergeSetting,
- (somSelf->GetDropResult(ev) == kODDropMove),
- contentSU,
- facet,
- viewType,
- result);
-
- return returnValue;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropInitDragAndDrop(ODDragAndDrop *somSelf, Environment *ev,
- ODSession* session)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropInitDragAndDrop");
-
- SOM_TRY
-
- /* Moved from somInit. SOM itself sets fields to zero
- _fSession = kODNULL;
- _fWindowState = kODNULL;
- _fStorageSystem = kODNULL;
-
- _fDragItemList = kODNULL;
- _fListFromHandler = false;
- _fDragItemIterator = kODNULL;
-
- _fAttributes = 0;
- _fDragReference = 0;
-
- _fPrevFacet = kODNULL;
- _fSourceFrame = kODNULL;
- _fSourcePart = kODNULL;
- _fDestFacet = kODNULL;
-
- _fReceiveHandler = kODNULL;
- _fTrackingHandler = kODNULL;
- _fSendDataHandler = kODNULL;
- _fFacetsRejected = kODNULL;
- */
-
- _fSession = session;
-
- somSelf->InitObject(ev);
-
- long gestaltResult;
- OSErr result;
-
- // Get the current process for background drag
- _fPSN = (ProcessSerialNumber*) ODNewPtr(sizeof(ProcessSerialNumber));
- GetCurrentProcess(_fPSN);
-
- _fReplaceFileEvent = (AppleEvent*) ODNewPtr(sizeof(AppleEvent));
- CreateReplaceFileEvent(ev,
- _fReplaceFileEvent,
- session,
- _fPSN);
-
- _fFacetsRejected = new OpenHashTable(OpenHashTable::StdEqual, OpenHashTable::StdHash, kODNULL);
- _fFacetsRejected->Initialize(kODInitialNumEntries,
- sizeof(ODFacet*),
- sizeof(ODFacet*));
-
- // Check if the drag manager is present
- result = Gestalt(gestaltDragMgrAttr, &gestaltResult);
- if (result != noErr)
- THROW_M(result, "Error from Gestalt");
-
- // The mysterious 31 is the bit position as BitTst uses a convention opposite to MC68000
- if (BitTst(&gestaltResult, (31 - gestaltDragMgrPresent)) == false) {
- THROW_M(kODErrNoDragManager, "No drag manager present");
- }
- else {
- // Install the default tracking handler for this application (session)
- _fTrackingHandler = NewDragTrackingHandlerProc(&MyDragTrackingHandler);
- result = InstallTrackingHandler(_fTrackingHandler, NULL, (void *) somSelf);
- ASSERTM(result == noErr, result, "Error from InstallTrackingHandler");
-
- // Install the default receive handler for this application (session)
- _fReceiveHandler = NewDragReceiveHandlerProc(&MyReceiveDropHandler);
- result = InstallReceiveHandler(_fReceiveHandler, NULL, (void *) somSelf);
- ASSERTM(result == noErr, result, "Error from InstallReceiveHandler");
-
- // Create a UPP for MySendDataProc which we will use later inside ::StartDrag
- _fSendDataHandler = NewDragSendDataProc(MySendDataProc);
-
- _fWindowState = _fSession->GetWindowState(ev);
-
- _fStorageSystem = _fSession->GetStorageSystem(ev);
-
- _fDragItemList = new LinkedList;
-
- AEEventHandlerUPP theHandlerUPP = NewAEEventHandlerProc( ReplaceFileAEHandler ) ;
- THROW_IF_ERROR(AEInstallEventHandler(kODShellSignature,
- kODReplaceFileEventID, theHandlerUPP, nil, false));
- }
-
- SOM_CATCH_ALL
-
- _fWindowState = kODNULL;
- _fStorageSystem = kODNULL;
- if (_fDragItemList)
- {
- delete _fDragItemList;
- _fDragItemList = kODNULL;
- }
- if (_fReceiveHandler)
- {
- RemoveReceiveHandler(_fReceiveHandler, NULL);
- DisposeRoutineDescriptor(_fReceiveHandler);
- _fReceiveHandler = kODNULL;
- }
- if (_fTrackingHandler)
- {
- RemoveTrackingHandler(_fTrackingHandler, NULL);
- DisposeRoutineDescriptor(_fTrackingHandler);
- _fTrackingHandler = kODNULL;
- }
- if (_fSendDataHandler)
- {
- DisposeRoutineDescriptor(_fSendDataHandler);
- _fSendDataHandler = kODNULL;
- }
-
- SOM_ENDTRY
- }
-
- SOM_Scope ODULong SOMLINK ODDragAndDropGetDragAttributes(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragAttributes");
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
-
- return _fAttributes;
- }
-
- SOM_Scope ODPlatformDragReference SOMLINK ODDragAndDropGetDragReference(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragReference");
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
-
- return _fDragReference;
- }
-
-
- SOM_Scope ODFacet* SOMLINK ODDragAndDropFindTargetFacet(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformWindow theWindow,
- ODPoint* mouse,
- ODPoint* localMouse)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropFindTargetFacet");
-
- ODFacet *targetFacet = kODNULL;
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
- else {
- SOM_TRY
- ODFacet *curFacet;
- GrafPtr curPort;
- Point qdLocal;
-
- { TempODWindow targetWindow = _fWindowState->AcquireODWindow(ev,theWindow);
- if (!targetWindow)
- return kODNULL;
-
- GetPort(&curPort);
- SetPort(theWindow);
- qdLocal = mouse->AsQDPoint();
- GlobalToLocal(&qdLocal);
- *localMouse = qdLocal;
-
- SetPort(curPort);
-
- curFacet = targetWindow->GetFacetUnderPointForDrag(ev,
- localMouse);
- }
-
- while (curFacet && !targetFacet)
- {
- ODFrame* curFrame = curFacet->GetFrame(ev);
- if (!curFrame->IsDragging(ev) &&
- curFrame->IsDroppable(ev) &&
- !curFrame->IsFrozen(ev) &&
- !_fFacetsRejected->Exists(&curFacet))
- {
- targetFacet = curFacet;
- }
- curFacet = curFacet->GetContainingFacet(ev);
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- return targetFacet;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropGetPromiseFromDragManager(ODDragAndDrop *somSelf, Environment *ev,
- ODPart* sourcePart,
- ODStorageUnitView* destSUView)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetPromiseFromDragManager");
-
- SOM_TRY
-
- if (_fTrackingHandler == kODNULL)
- THROW(kODErrNoDragManager);
-
- OSErr err;
-
- if (sourcePart != kODNULL) {
-
- ItemReference dragItemRef;
- err = GetDragItemReferenceNumber(_fDragReference, 1, &dragItemRef);
- ASSERTM(err == noErr, err, "Cannot get drag item reference in GetPromiseFromDragManager");
-
- ODPromiseDesc theInfo;
- theInfo.sourcePart = sourcePart;
- theInfo.destSUView = destSUView;
-
- // Set the offset of the suview to the beginning of the value
- destSUView->SetOffset(ev, 0);
-
- AEDesc dropLocation;
- err = AECreateDesc(kODPromiseDesc, (Ptr) &theInfo, sizeof(theInfo), &dropLocation);
- ASSERTM(err == noErr, err, "Error from AECreateDesc in GetPromiseFromDragManager");
-
- err = SetDropLocation(_fDragReference, &dropLocation);
- ASSERTM(err == noErr, err, "Error from SetDropLocation in GetPromiseFromDragManager");
-
- gIsResolvingPromise = kODTrue;
-
- long resolveResult;
- Size resolveSize = sizeof(long);
-
- err = GetFlavorData(_fDragReference, dragItemRef, kODPromiseFlavor, &resolveResult, &resolveSize, 0);
- ASSERTM(err == cantGetFlavorErr, err, "Cannot GetFlavorData in GetPromiseFromDragManager");
-
- AEDisposeDesc(&dropLocation);
-
- // Reset the Drop location.
-
- gIsResolvingPromise = kODFalse;
-
- theInfo.sourcePart = kODNULL;
- theInfo.destSUView = kODNULL;
-
- err = AECreateDesc(kODPromiseDesc, (Ptr) &theInfo, 0, &dropLocation);
- ASSERTM(err == noErr, err, "Error from AECreateDesc in GetPromiseFromDragManager");
-
- err = SetDropLocation(_fDragReference, &dropLocation);
- ASSERTM(err == noErr, err, "Error from SetDropLocation in GetPromiseFromDragManager");
-
- AEDisposeDesc(&dropLocation);
- }
- else {
- ODHandle dataHandle = kODNULL;
- ODType isoType = kODNULL;
- TRY
-
- ODTranslation* translate = _fSession->GetTranslation(ev);
- isoType = destSUView->GetType(ev);
- if (ODISOStrNCompare((ODISOStr) isoType,(ODISOStr) kODAppleFileTypePrefix, ODISOStrLength(kODAppleFileTypePrefix)) != 0) {
- ItemReference theItem;
- OSErr result;
- destSUView->SetOffset(ev,0);
- StorageUnitViewGetValue(destSUView, ev, sizeof(ItemReference), &theItem);
- ODPlatformType platformType = translate->GetPlatformTypeFromISOType(ev, isoType);
- if ( platformType == kODScrapTypestxt && !DragItemHasFlavor(_fDragReference, theItem, kODScrapTypestxt) )
- {
- // Create styled text from 'styl' and 'TEXT' flavors
- #ifdef ODDebug_DragAndDrop
- somPrintf("GetPromiseFromDragManager: Creating 'stxt' from 'styl' and 'TEXT'\n");
- #endif
- destSUView->SetOffset(ev,0);
- result = CopyFromDragItemInChunks(ev, kODScrapTypestyl, theItem, _fDragReference, destSUView);
- destSUView->SetOffset(ev, destSUView->GetSize(ev));
- result = CopyFromDragItemInChunks(ev, kODScrapTypeTEXT, theItem, _fDragReference, destSUView);
- }
- else
- {
- destSUView->SetOffset(ev,0);
- result = CopyFromDragItemInChunks(ev, platformType, theItem, _fDragReference, destSUView);
- }
- }
- ODDisposePtr(isoType);
-
- CATCH_ALL
-
- if (dataHandle)
- ODDisposeHandle(dataHandle);
- if (isoType)
- ODDisposePtr(isoType);
- RERAISE;
-
- ENDTRY
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
-
- SOM_Scope void SOMLINK ODDragAndDropGetDataFromDragManager(ODDragAndDrop *somSelf, Environment *ev,
- ODStorageUnitView* suView)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDataFromDragManager");
-
- WARN("ODDragAndDropGetDataFromDragManager is obsoleted.\n");
- }
-
- SOM_Scope void SOMLINK ODDragAndDropsomUninit(ODDragAndDrop *somSelf)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropsomUninit");
-
- if (_fDragItemList)
- {
- _fDragItemList->DeleteAllLinks();
- delete _fDragItemList;
- }
- if (_fDragItemIterator)
- delete _fDragItemIterator;
- if (_fReceiveHandler)
- {
- RemoveReceiveHandler(_fReceiveHandler, NULL);
- DisposeRoutineDescriptor(_fReceiveHandler);
- }
- if (_fTrackingHandler)
- {
- RemoveTrackingHandler(_fTrackingHandler, NULL);
- DisposeRoutineDescriptor(_fTrackingHandler);
- }
- if (_fSendDataHandler)
- {
- DisposeRoutineDescriptor(_fSendDataHandler);
- }
-
- ODDeleteObject(_fFacetsRejected);
-
- ODDisposePtr(_fPSN);
- ODDisposePtr(_fReplaceFileEvent);
- }
-
- SOM_Scope void SOMLINK ODDragAndDropClear(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropClear");
-
- #if ODDebug_DragAndDrop
- somPrintf("In Clear\n");
- #endif
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
- else {
- SOM_TRY
- if (_fDragItemIterator)
- {
- delete _fDragItemIterator;
- _fDragItemIterator = kODNULL;
- }
- _fDragItemList->DeleteAllLinks();
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- }
-
- SOM_Scope ODStorageUnit* SOMLINK ODDragAndDropGetContentStorageUnit(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetContentStorageUnit");
-
- ODStorageUnit* contentSU = kODNULL;
-
- if (_fTrackingHandler == kODNULL)
- ODSetSOMException(ev, kODErrNoDragManager);
- else {
- SOM_TRY
-
- ODMemDragItem *newItem;
- ODDragLink *newLink;
-
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(_fStorageSystem, kODFalse);
- ASSERTM(newItem != kODNULL, kODErrCannotAllocateDragItem, "Error allocating drag item");
- newItem->Initialize(ev);
- newLink = new ODDragLink(newItem, kODTrue);
- if (!newLink)
- {
- delete newItem;
- ASSERTM(newLink != kODNULL, kODErrCannotAllocateDragItem, "Error allocating drag link");
- }
- _fDragItemList->AddLast(newLink);
- contentSU = newItem->fSU;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
- }
- return contentSU;
- }
-
- SOM_Scope ODDropResult SOMLINK ODDragAndDropStartDrag(ODDragAndDrop *somSelf, Environment *ev,
- ODFrame* srcFrame,
- ODType imageType,
- ODByteArray* image,
- ODPart** destPart,
- ODByteArray* refCon)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropStartDrag");
-
- LinkedListIterator *theIter = kODNULL; ODVolatile(theIter);
-
- SOM_TRY
- if (_fTrackingHandler == kODNULL)
- THROW(kODErrNoDragManager);
-
- ASSERT(image != kODNULL, kODErrIllegalNullInput);
- ASSERT(refCon != kODNULL, kODErrIllegalNullInput);
-
- OSErr result;
- RgnHandle imageRgn;
- ODTranslation *translate;
- ODULong count, index;
- ODType theISOType;
- ODPlatformType platformType;
- PromiseHFSFlavor thePromise;
- ODStorageUnit *theSU;
- ODDragLink *theDragLink;
-
- // Check if we know what the image type is
- ASSERTM(ODISOStrEqual(imageType, kODDragImageRegionHandle), kODErrUnknownDragImageType, "Unknown image type in StartDrag");
-
- // Set the drop result to kODDropFail. - VL
- _fDropResult = kODDropFail;
-
- // Begin the drag by creating a new drag reference
- result = NewDrag(&_fDragReference);
- ASSERTM(result == noErr, result, "Bad result from NewDrag");
-
- #ifdef ODDebug_DragAndDrop
- // PrintDragReference(_fDragReference, "After NewDrag");
- #endif
-
- // Register a send procedure so we don't have to cache any data with the drag manager
- result = SetDragSendProc(_fDragReference, _fSendDataHandler, (void *) somSelf);
- ASSERTM(result == noErr, result, "Bad result from SetDragSendProc");
-
- // Scan through all items in the drag and add a flavor for each value
- // in the storage unit's kODContents property
- theIter = new LinkedListIterator(_fDragItemList);
- translate = _fSession->GetTranslation(ev);
- imageRgn = *((RgnHandle*) image->_buffer);
- for (theDragLink = (ODDragLink*)theIter->First(); theDragLink; theDragLink = (ODDragLink*)theIter->Next())
- {
- theSU = theDragLink->fItem->fSU;
- ODBoolean userPromise = ODSUExistsThenFocus(ev, theSU, kODPropContents, kODHFSPromise);
- if (userPromise)
- {
- ODByteArray ba;
- ODPart* dummySourcePart;
- theSU->GetPromiseValue(ev, kODHFSPromise, 0, sizeof(PromiseHFSFlavor), &ba, &dummySourcePart);
- if (ba._buffer)
- {
- ODBlockMove(ba._buffer, &thePromise, ba._length);
- ODDisposePtr(ba._buffer);
- }
- thePromise.promisedFlavor = kODUserPromiseFlavor;
- }
- else {
- // Always promise a file in case somebody wishes to drag this out to the finder
- thePromise.fileType = kODBentoFlavor;
- thePromise.fileCreator = kODShellSignature;
- thePromise.fdFlags = 0;
- thePromise.promisedFlavor = kODBentoFlavor;
- }
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), flavorTypePromiseHFS,
- &thePromise, sizeof(PromiseHFSFlavor), 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
-
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), (userPromise ? kODUserPromiseFlavor : kODBentoFlavor), 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
-
- result = SetDragItemBounds(_fDragReference, (ItemReference)(theDragLink->fItem), &((**imageRgn).rgnBBox));
- ASSERTM(result == noErr, result, "Bad result from SetDragItemBounds");
-
- #ifdef ODDebug_DragAndDrop
- // PrintStorageUnit(ev, theSU, "DragItem SU");
- #endif
- theSU->Focus(ev,kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
- count = theSU->CountValues(ev);
- for (index = 1; index <= count; ++index)
- {
- theSU->Focus(ev,kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
- theISOType = theSU->GetType(ev);
- platformType = translate->GetPlatformTypeFromISOType(ev, theISOType);
- ODDisposePtr(theISOType);
- if (!platformType)
- continue;
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), platformType, 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
-
- // If styled text ('stxt') was just added, also add 'stly' if
- // a 'TEXT' representation will also be written.
- if ( (platformType == kODScrapTypestxt)
- && theSU->Exists(ev, kODPropContents, kODAppleTEXT, 0)
- && !theSU->Exists(ev, kODPropContents, kODApplestyl, 0) )
- {
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), kODScrapTypestyl, 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from AddDragItemFlavor");
- }
- }
-
- // Always add our special dummy promise to the drag
- result = AddDragItemFlavor(_fDragReference, (ItemReference)(theDragLink->fItem), kODPromiseFlavor, 0L, 0L, 0);
- ASSERTM(result == noErr, result, "Bad result from adding kODPromiseFlavor");
- }
- ODBoolean oldDelayFatal = gODDelayBentoFatalError;
- gODDelayBentoFatalError = kODTrue; // no exit to shell inside Drag Mgr
-
- _fSourceFrame = srcFrame;
- _fSourcePart = srcFrame->AcquirePart(ev);
- TRY
- _fDestFacet = kODNULL;
- _fDragItemIterator = new ODDragItemIterator();
- THROW_IF_NULL(_fDragItemIterator, kODErrOutOfMemory);
- _fDragItemIterator->InitDragItemIterator(ev, theIter);
- _fHasLeftSourceFrame = kODFalse;
- _fHasLeftSourcePart = kODFalse;
-
- #ifdef ODDebug_DragAndDrop
- // PrintDragReference(_fDragReference, "Before TrackDrag");
- #endif
-
- // Do the drag
- result = TrackDrag(_fDragReference, *((EventRecord**) refCon->_buffer), imageRgn);
-
- if (_fDestFacet)
- *destPart = _fDestFacet->GetFrame(ev)->AcquirePart(ev);
- else
- *destPart = kODNULL;
- CATCH_ALL
- DisposeDrag(_fDragReference);
- _fDragReference = kODNULL;
- ODReleaseObject(ev, _fSourcePart);
- RERAISE;
- ENDTRY
-
- gODDelayBentoFatalError = oldDelayFatal;
- if ( gODBentoFatalErrorHasOccurred && !gODDelayBentoFatalError )
- ODBentoFatalError();
-
- DisposeDrag(_fDragReference);
- _fDragReference = kODNULL;
- _fSourceFrame = kODNULL;
- ODReleaseObject(ev, _fSourcePart);
- _fDestFacet = kODNULL;
- somSelf->Clear(ev);
-
- if (_fShouldSendReplaceFileEvent)
- {
- _fShouldSendReplaceFileEvent = kODFalse;
- OSErr err = SetupReplaceFileEvent(ev,
- _fReplaceFileEvent,
- &gTmpFileFSSpec,
- &gTargetFSSpec);
- SendReplaceFileEvent(_fReplaceFileEvent, _fPSN);
- DisposeReplaceFileEvent(_fReplaceFileEvent);
- CreateReplaceFileEvent(ev,
- _fReplaceFileEvent,
- _fSession,
- _fPSN);
- }
-
- SOM_CATCH_ALL
-
- delete theIter;
- if (_fDragReference)
- DisposeDrag(_fDragReference);
- _fDragReference = kODNULL;
-
- SOM_ENDTRY
-
- if (_fDropResult == kODDropMove)
- return kODDropMove;
- else if (_fDropResult == kODDropCopy)
- return kODDropCopy;
- else
- return kODDropFail;
- }
-
-
- SOM_Scope LinkedList* SOMLINK ODDragAndDropGetDragItemList(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragItemList");
-
- return _fDragItemList;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDragItemList(ODDragAndDrop *somSelf, Environment *ev,
- LinkedList* list)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDragItemList");
-
- _fDragItemList = list;
- }
-
- SOM_Scope ODBoolean SOMLINK ODDragAndDropGetListFromHandler(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetListFromHandler");
-
- return _fListFromHandler;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetListFromHandler(ODDragAndDrop *somSelf, Environment *ev,
- ODBoolean listFromHandler)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetListFromHandler");
-
- _fListFromHandler = listFromHandler;
- }
-
- SOM_Scope ODFrame* SOMLINK ODDragAndDropGetSourceFrame(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetSourceFrame");
-
- return _fSourceFrame;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetSourceFrame(ODDragAndDrop *somSelf, Environment *ev,
- ODFrame* sourceFrame)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetSourceFrame");
-
- _fSourceFrame = sourceFrame;
- }
-
- SOM_Scope ODULong SOMLINK ODDragAndDropGetAttributes(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetAttributes");
-
- return _fAttributes;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetAttributes(ODDragAndDrop *somSelf, Environment *ev,
- ODULong attr)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetAttributes");
-
- _fAttributes = attr;
- }
-
- SOM_Scope ODPart* SOMLINK ODDragAndDropGetSourcePart(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetSourcePart");
-
- return _fSourcePart;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetSourcePart(ODDragAndDrop *somSelf, Environment *ev,
- ODPart* sourcePart)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetSourcePart");
-
- _fSourcePart = sourcePart;
- }
-
- SOM_Scope ODDragItemIterator* SOMLINK ODDragAndDropGetDragItemIterator(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDragItemIterator");
-
- return _fDragItemIterator;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDragItemIterator(ODDragAndDrop *somSelf, Environment *ev,
- ODDragItemIterator* iter)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDragItemIterator");
-
- _fDragItemIterator = iter;
- }
-
- SOM_Scope ODSession* SOMLINK ODDragAndDropGetSession(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetSession");
-
- return _fSession;
- }
-
- SOM_Scope ODStorageSystem* SOMLINK ODDragAndDropGetStorageSystem(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetStorageSystem");
-
- return _fStorageSystem;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDragReference(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference dragReference)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDragReference");
-
- _fDragReference = dragReference;
- }
-
- SOM_Scope ODFacet* SOMLINK ODDragAndDropGetPrevFacet(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetPrevFacet");
-
- return _fPrevFacet;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetPrevFacet(ODDragAndDrop *somSelf, Environment *ev,
- ODFacet* prevFacet)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetPrevFacet");
-
- _fPrevFacet = prevFacet;
- }
-
- SOM_Scope ODFacet* SOMLINK ODDragAndDropGetDestFacet(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDestFacet");
-
- return _fDestFacet;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDestFacet(ODDragAndDrop *somSelf, Environment *ev,
- ODFacet* destFacet)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDestFacet");
-
- _fDestFacet = destFacet;
- }
-
- SOM_Scope ODDropResult SOMLINK ODDragAndDropGetDropResult(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- return _fDropResult;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetDropResult(ODDragAndDrop *somSelf, Environment *ev,
- ODDropResult dropResult)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropSetDropResult");
-
- _fDropResult = dropResult;
- }
-
- SOM_Scope ProcessSerialNumber* SOMLINK ODDragAndDropGetPSN(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- return _fPSN;
- }
-
- SOM_Scope AppleEvent* SOMLINK ODDragAndDropGetReplaceFileEvent(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- return _fReplaceFileEvent;
- }
-
- SOM_Scope void SOMLINK ODDragAndDropSetShouldSendReplaceFileEvent(ODDragAndDrop *somSelf, Environment *ev,
- ODBoolean shouldSend)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropGetDropResult");
-
- _fShouldSendReplaceFileEvent = shouldSend;
- }
-
- ODBoolean DragItemHasFlavor(ODPlatformDragReference theDrag, ItemReference itemID, OSType theType)
- {
- ODBoolean result = kODFalse;
- ODUShort count;
- ODUShort j;
- OSType itemType;
-
- CountDragItemFlavors(theDrag, itemID, &count);
- for (j = 1; j <= count; j++)
- {
- OSErr err = GetFlavorType(theDrag, itemID, j, &itemType);
- if ( err != noErr )
- break;
- if (itemType == theType)
- {
- result = kODTrue;
- break;
- }
- }
-
- return result;
- }
-
- pascal OSErr MyDragTrackingHandler(
- short message,
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDrop *self = (ODDragAndDrop*)handlerRefCon;
- ODPoint mouse, localMouse;
- OSErr returnCode = noErr;
-
- ODBoolean oldDelayFatal = gODDelayBentoFatalError;
- gODDelayBentoFatalError = kODTrue; // no exit to shell inside Drag Mgr
-
- TRY
-
- Environment* ev = somGetGlobalEnvironment();
-
- switch (message)
- {
- case dragTrackingEnterHandler:
- returnCode = self->EnterHandler(ev, theDrag);
- break;
- case dragTrackingEnterWindow:
- returnCode = self->EnterWindow(ev, theDrag, theWindow);
- break;
-
- case dragTrackingInWindow:
- returnCode = self->InWindow(ev, theDrag, theWindow);
- break;
-
- case dragTrackingLeaveWindow:
- returnCode = self->LeaveWindow(ev, theDrag, theWindow);
- break;
-
- case dragTrackingLeaveHandler:
- returnCode = self->LeaveHandler(ev);
- break;
- }
-
- CATCH_ALL
-
- returnCode = ErrorCode();
-
- ENDTRY
-
- gODDelayBentoFatalError = oldDelayFatal;
-
- return returnCode;
- }
-
- pascal OSErr MyReceiveDropHandler(
- WindowPtr theWindow,
- void* handlerRefCon,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDrop *self = (ODDragAndDrop*)handlerRefCon;
- ODPoint mouse, localMouse;
- Point qdMouse;
- ODFacet *targetFacet;
- OSErr returnCode = noErr;
-
- #ifdef ODDebug_DragAndDrop
- somPrintf("MyReceiveDropHandler\n");
- #endif
-
- ODBoolean oldDelayFatal = gODDelayBentoFatalError;
- gODDelayBentoFatalError = kODTrue; // no exit to shell inside Drag Mgr
-
- Environment* ev = somGetGlobalEnvironment();
-
- TRY
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- targetFacet = self->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- if (!targetFacet || !(self->GetDragItemList(ev)->Count()))
- returnCode = dragNotAcceptedErr;
- else
- {
- TempODPart targetPart = targetFacet->GetFrame(ev)->AcquirePart(ev);
-
- // Assume _fDropResult is kODDropMove
-
- self->SetDropResult(ev, kODDropMove);
-
- // Are we going across Drafts?
-
- ODPart* sourcePart = self->GetSourcePart(ev);
- if ((sourcePart == kODNULL) ||
- (targetPart->GetStorageUnit(ev)->GetDraft(ev) !=
- sourcePart->GetStorageUnit(ev)->GetDraft(ev)))
- self->SetDropResult(ev, kODDropCopy);
-
- ODSShort mouseDownModifiers;
- ODSShort mouseUpModifiers;
-
- GetDragModifiers(self->GetDragReference(ev), 0L, &mouseDownModifiers, &mouseUpModifiers);
-
- // Check the mandatory modifier keys first
-
- if (mouseUpModifiers & optionKey) {
- self->SetDropResult(ev, kODDropCopy);
- SetPasteAsAttribute(self, ev, mouseUpModifiers);
- }
- else if (mouseUpModifiers & controlKey) {
- self->SetDropResult(ev, kODDropMove);
- SetPasteAsAttribute(self, ev, mouseUpModifiers);
- }
- else if (mouseUpModifiers & cmdKey) {
- SetPasteAsAttribute(self, ev, mouseUpModifiers);
- }
-
- // Then check the optional modifier keys
-
- else if (mouseDownModifiers & optionKey) {
- self->SetDropResult(ev, kODDropCopy);
- SetPasteAsAttribute(self, ev, mouseDownModifiers);
- }
- else if (mouseDownModifiers & controlKey) {
- self->SetDropResult(ev, kODDropMove);
- SetPasteAsAttribute(self, ev, mouseDownModifiers);
- }
- else if (mouseDownModifiers & cmdKey) {
- SetPasteAsAttribute(self, ev, mouseDownModifiers);
- }
-
- // Check to see whether it is an override by source part.
- ODDragItemIterator* dragItemIter = self->GetDragItemIterator(ev);
- if (dragItemIter)
- {
- ODStorageUnit* su = dragItemIter->First(ev);
- ODDraft* draft = su->GetDraft(ev);
- ODCloneKind cloneKind = GetOriginalCloneKind(ev, draft);
- if (cloneKind == kODCloneCopy)
- self->SetDropResult(ev, kODDropCopy);
- }
-
- // Drop
- #ifdef ODDebug_DragAndDrop
- somPrintf("Calling Drop on targetFacet %x\n", targetFacet);
- #endif
-
- self->SetAttributes(ev, self->GetAttributes(ev) |
- (self->GetDropResult(ev) == kODDropMove ? kODDropIsMove : kODDropIsCopy));
-
- if (targetFacet->GetFrame(ev) == self->GetSourceFrame(ev))
- self->SetAttributes(ev, self->GetAttributes(ev) | (kODDropIsInSourceFrame | kODDropIsInSourcePart));
- else if (targetPart == self->GetSourcePart(ev))
- self->SetAttributes(ev, self->GetAttributes(ev) | kODDropIsInSourcePart);
-
- self->SetDestFacet(ev, targetFacet);
- self->SetPrevFacet(ev, kODNULL);
- ODULong dropResult = targetFacet->Drop(ev, &localMouse, self->GetDragItemIterator(ev), kODNULL);
-
- if (dropResult == kODDropFail) {
- self->SetDropResult(ev, dropResult);
- returnCode = dragNotAcceptedErr;
- }
- else if ((self->GetDropResult(ev) == kODDropMove) && (dropResult == kODDropCopy)) {
- self->SetDropResult(ev, kODDropCopy);
- returnCode = noErr;
- }
-
- ODDragItemIterator* iter = self->GetDragItemIterator(ev);
- ODSession* destSession = self->GetSession(ev);
- for (ODStorageUnit* su = iter->First(ev); iter->IsNotComplete(ev); su = iter->Next(ev)) {
- ODSession* sourceSession = su->GetSession(ev);
- if ((sourceSession != kODNULL) && (sourceSession != destSession)) {
- ODDragAndDrop* sourceDAD = sourceSession->GetDragAndDrop(ev);
- if (sourceDAD != kODNULL) {
- sourceDAD->SetDropResult(ev, self->GetDropResult(ev));
- sourceDAD->SetDestFacet(ev, targetFacet);
- }
- }
- }
- // ODSession* sourceSession = sourcePart->AcquireStorageUnit(ev)->GetSession(ev);
- // if (sourceSession != self->GetSession(ev)) {
- // ODDragAndDrop* sourceDAD = sourceSession->GetDragAndDrop(ev);
- // sourceDAD->SetDropResult(ev, self->GetDropResult(ev));
- // sourceDAD->SetDestFacet(ev, targetFacet);
- // }
- // }
- }
-
- CATCH_ALL
- gODDelayBentoFatalError = oldDelayFatal;
-
- self->SetDropResult(ev, kODDropFail);
- returnCode = dragNotAcceptedErr;
- #if ODDebug
- somPrintf("Error in MyReceiveDropHandler.\n");
- #endif
-
- ENDTRY
-
- gODDelayBentoFatalError = oldDelayFatal;
-
- ODEventData event;
- WaitNextEvent(mUpMask, (EventRecord*) &event, 0, kODNULL);
- #if ODDebug_DragAndDrop
- somPrintf("message %x when %x where %x modifier %x\n", event.message, event.when, event.where, event.modifiers);
- #endif
-
- return returnCode;
- }
-
- pascal OSErr MySendDataProc(
- FlavorType theType,
- void* refCon,
- ItemReference theItem,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDrop *self = (ODDragAndDrop*)refCon;
- Environment* ev = somGetGlobalEnvironment();
- OSErr result = noErr;
- ODType theISOType;
- ODTranslation *translate;
- AEDesc dropDescriptor;
- ODPtr stylPtr = kODNULL;
- ODULong stylSize = 0;
-
- ODBoolean oldDelayFatal = gODDelayBentoFatalError;
- gODDelayBentoFatalError = kODTrue; // no exit to shell inside Drag Mgr
-
- ODVolatile(result);
- TRY
-
- LinkedListIterator iter(self->GetDragItemList(ev));
- ODDragLink* theDragLink = kODNULL;
- ODMemDragItem* theDragItem = kODNULL;
-
- #ifdef ODDebug_DragAndDrop
- somPrintf("Entering MySendDataProc.\n");
- #endif
-
- for (theDragLink = (ODDragLink*)iter.First();
- theDragLink; theDragLink = (ODDragLink*)iter.Next())
- {
- if (theDragLink->fItem == (ODDragItem*)theItem)
- {
- theDragItem = (ODMemDragItem*) theDragLink->fItem;
- break;
- }
- }
- if (!theDragItem)
- {
- WARN("Item not found in send proc");
- result = badDragFlavorErr;
- }
- else {
- switch (theType)
- {
- case kODPromiseFlavor:
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: kODPromiseFlavor\n");
- #endif
- if (gIsResolvingPromise)
- {
- result = GetDropLocation(theDrag, &dropDescriptor);
- if ((result != noErr) || (dropDescriptor.descriptorType != kODPromiseDesc)) {
- WARN("Error from GetDropLocation in send procedure");
- }
- else {
- ODPromiseDesc theInfo;
- ODBlockMove((Ptr)(*dropDescriptor.dataHandle), (Ptr)&theInfo, sizeof(ODPromiseDesc));
- if (theInfo.sourcePart && theInfo.destSUView)
- {
- TRY
- theInfo.sourcePart->FulfillPromise(ev, theInfo.destSUView);
- CATCH_ALL
- WARN("Error from FulfillPromise.");
- ENDTRY
- }
- result = noErr;
- }
- }
- break;
- case kODUserPromiseFlavor:
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: kODUserPromiseFlavor\n");
- #endif
- result = noErr;
- ODStorageUnit* contentSU = theDragItem->fSU;
- if ((contentSU != kODNULL) && (contentSU->Exists(ev, kODPropContents, kODHFSPromise, 0)))
- {
- FSSpec dropFSSpec;
- result = GetDropFSSpec(theDrag, dropFSSpec);
- if (result == noErr)
- {
- TRY
- contentSU->Focus(ev, kODPropContents, kODPosUndefined, kODHFSPromise, 0, kODPosUndefined);
- StorageUnitSetPromiseValue(contentSU, ev, kODHFSPromise, 0, sizeof(FSSpec), &dropFSSpec, self->GetSourcePart(ev));
- contentSU->Focus(ev, kODPropContents, kODPosUndefined, kODHFSPromise, 0, kODPosUndefined);
- ODULong size = StorageUnitGetValue(contentSU, ev, sizeof(FSSpec), &dropFSSpec);
- if (size != sizeof(FSSpec))
- {
- self->SetDropResult(ev, kODDropFail);
- result = fnfErr;
- }
- else
- {
- self->SetDropResult(ev, IsTrashFolder(dropFSSpec) ? kODDropMove : kODDropCopy);
- SetDragItemFlavorData(theDrag, theItem, theType, &dropFSSpec, sizeof(FSSpec), 0L);
- }
- CATCH_ALL
- WARN("Error from FulfillPromise.");
- ENDTRY
- }
- // If we get a file not found error, most likely we are trying to drag to somewhere other than the Finder.
- // That's OK, so just eat the error.
- if( result == fnfErr )
- result = noErr;
- }
- break;
- case kODBentoFlavor:
- {
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: kODBentoFlavor\n");
- #endif
- // Check the drop location (probably from the finder)
- FSSpec dropFSSpec;
-
- result = GetDropFSSpec(theDrag, dropFSSpec);
- if (result == noErr)
- {
- boolean nameFromPart = MakeUniqueFilename(ev, self->GetSession(ev), theDragItem->fSU, &dropFSSpec);
-
- // Drags to the Trash are always a move
- ODULong dropResult;
- boolean isDraggingToTrash = IsTrashFolder(dropFSSpec);
- if( isDraggingToTrash )
- dropResult = kODDropMove; // Dragged to Trash, so it's a move
- else
- dropResult = kODDropCopy;
- self->SetDropResult(ev, dropResult);
-
- if (isDraggingToTrash)
- {
- TempPlatformFile file = new PlatformFile;
- file->Specify(&dropFSSpec);
-
- if (file->Exists())
- {
- // If the target file exists in trash already,
- // set the fsspec to the temp folder.
- RespecifyToTempFolder(file);
-
- // Clone the data.
- CloneIntoFile(ev, theDragItem, file->GetFileSpec());
-
- // After cloning the data to the file (in temp folder),
- // move to it trash.
- file->MoveToTrash();
-
- // Set the result for Drag Manager.
- SetDragItemFlavorData(theDrag, theItem, theType, &(file->GetFileSpec()), sizeof(FSSpec), 0L);
- }
- else
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- else if (!nameFromPart)
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- else if (IsFrontProcess())
- {
- TempPlatformFile file = new PlatformFile;
- file->Specify(&dropFSSpec);
-
- if (file->Exists())
- {
- ParamText(dropFSSpec.name, "\p", "\p", "\p");
- if (ODAskUserReplace(ev, self->GetSession(ev)))
- {
- file->MoveToTrash();
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- else
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- else
- {
- TempPlatformFile file = new PlatformFile;
- file->Specify(&dropFSSpec);
-
- if (file->Exists())
- {
- FSSpec targetFSSpec = file->GetFileSpec();
- RespecifyToTempFolder(file);
- FSSpec tmpFileFSSpec = file->GetFileSpec();
- CloneIntoFile(ev, theDragItem, tmpFileFSSpec);
- // Not notifying the target through SetDragItemData on purpose becuase we are going all the work.
-
- gTargetFSSpec = targetFSSpec;
- gTmpFileFSSpec = tmpFileFSSpec;
- self->SetShouldSendReplaceFileEvent(ev, kODTrue);
- }
- else
- {
- CloneIntoFlavor(ev, self, theDragItem,
- theDrag, theItem, theType,
- dropFSSpec);
- }
- }
- }
- // If we are not dragging to a file, create a Drag item for the Bento Container.
- // This allows other applications to support OpenDoc Bento types (like the Scrapbook,
- // or Container apps).
- else if ( result == fnfErr )
- {
- // At this point, Doug says only a memory container is being modified in any way,
- // so we can suppress fatal errors:
- ODBoolean oldSuppress = gODSuppressBentoFatalError;
- gODSuppressBentoFatalError = kODTrue;
-
- OSErr e =
- CopyMemContainerToDragItemInChunks( ev, self->GetSession(ev), theType, theItem, theDrag, theDragItem );
-
- gODSuppressBentoFatalError = oldSuppress; // neutral
-
- return e;
- }
- }
- break;
- default:
- #ifdef ODDebug_DragAndDrop
- somPrintf("MySendDataProc: Default\n");
- #endif
- self->SetDropResult(ev, kODDropFail);
- translate = self->GetSession(ev)->GetTranslation(ev);
- theISOType = translate->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType);
- if (ODSUExistsThenFocus(ev, theDragItem->fSU,kODPropContents, theISOType))
- {
- result = CopyToDragItemInChunks(ev, theType, theItem, theDrag, theDragItem);
- if (result == noErr)
- self->SetDropResult(ev, kODDropCopy);
- }
- else if ( (theType == kODScrapTypestyl) && StorageUnitGetStylFromStyledText(theDragItem->fSU, ev, &stylSize, &stylPtr) )
- {
- result = SetDragItemFlavorData(theDrag, theItem, theType, stylPtr, stylSize, 0L);
- WASSERTM(result == noErr, "Error from SetDragItemFlavorData in send procedure");
- if (result == noErr)
- self->SetDropResult(ev, kODDropCopy);
- ODDisposePtr(stylPtr);
- stylPtr = kODNULL;
- }
- else
- {
- WARN("Send procedure can not supply this type");
- result = badDragFlavorErr;
- }
- ODDisposePtr(theISOType);
- }
- }
-
- CATCH_ALL
- gODDelayBentoFatalError = oldDelayFatal;
- self->SetShouldSendReplaceFileEvent(ev, kODFalse);
- result = ErrorCode();
- WARN("MySendDataProc: %d", result);
- ENDTRY
- gODDelayBentoFatalError = oldDelayFatal;
-
- return result;
- }
-
- static OSErr CopyMemContainerToDragItemInChunks(Environment* ev,
- ODSession* theSession,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem)
- {
- const ODULong kCopyBlockSize = 512;
- OSErr result = noErr;
- ODPtr dataPtr;
- ODULong dataSize;
-
- TRY
- // Now write out the entire Container for the Memory Drag item.
- ODMemDragItem* tempDItem = (ODMemDragItem*)theDragItem;
-
- // Clone the D&D container to a temp draft, then return the data handle from the temp container.
- // We cannot directly get the data handle from the D&D container, because the full data isn't written
- // until we close the container, but we can't do that yet because there could be further promises
- // pending against it.
- TempODHandle theMemDragItemContainerData = CloneToTempMemContainer( ev, tempDItem, theSession );
-
- ODLockHandle( theMemDragItemContainerData );
-
- dataPtr = *theMemDragItemContainerData;
- dataSize = ODGetHandleSize( theMemDragItemContainerData );
- WASSERTM( dataSize != 0, "Zero size memory container handle.");
-
- ODULong currentByte = 0;
- while ((currentByte < dataSize) && (result == noErr)) {
- ODULong bytesRead;
- if( ( dataSize - currentByte ) >= kCopyBlockSize )
- bytesRead = kCopyBlockSize;
- else
- bytesRead = dataSize - currentByte;
-
- result = SetDragItemFlavorData(theDrag, theItem, theType, ODPtr((ODULong)dataPtr + currentByte), bytesRead, currentByte);
- WASSERTM(result == noErr, "Error from SetDragItemFlavorData in CopyToDragItemInChunks.");
- currentByte += bytesRead;
- }
- WASSERTM(currentByte == dataSize, "Bytes written is NOT equal to dataSize.");
- CATCH_ALL
- result = dragNotAcceptedErr;
- ENDTRY
- return result;
- }
-
- static ODHandle CloneToTempMemContainer( Environment* ev, ODMemDragItem* tempDItem, ODSession* theSession )
- {
- ODStorageUnit* contentSU = tempDItem->fSU;
- ODID targetContentFrameID = kODNULLID;
- ODHandle containerHandle = ODNewHandle(0);
- ODStorageUnitID suID;
- TRY
- TempODContainer tempContainer = CreateMemoryContainer(ev, theSession, containerHandle, kODBentoMemoryContainer);
- TempODDocument tempDocument = tempContainer->AcquireDocument(ev, kODDefaultDocument);
- TempODDraft targetDraft = tempDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- TempODStorageUnit targetSU = targetDraft->CreateStorageUnit(ev);
-
- { TempODStorageUnit draftProperties = targetDraft->AcquireDraftProperties(ev);
- ODSetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef,targetSU->GetID(ev));
- suID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
- }
-
- ODDraft* sourceDraft = contentSU->GetDraft(ev);
- ODDraftKey cloneKey = 0;
- TRY
- cloneKey = sourceDraft->BeginClone(ev, targetDraft, kODNULL, kODCloneToFile);
- sourceDraft->Clone(ev, cloneKey, contentSU->GetID(ev), targetSU->GetID(ev), 0);
- ODID contentFrameID = ODGetWeakSURefProp(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef);
- if (contentFrameID != kODNULLID)
- {
- targetContentFrameID = sourceDraft->Clone(ev, cloneKey, contentFrameID, kODNULLID, 0);
- }
- sourceDraft->EndClone(ev, cloneKey);
- CATCH_ALL
- sourceDraft->AbortClone(ev, cloneKey);
-
- ENDTRY
-
- ODSURemoveProperty(ev, targetSU, kODPropMouseDownOffset);
-
- // first externalize the container
- // Externalize may fail with an iterator-out-of-sync error because
- // resolving promises may add storage units to the draft's collection
- // during iteration. In theory, the only promises should be in the
- // root storage unit, so explicitly externalize it first to resolve
- // promises before interating over all storage units.
- if( targetSU )
- targetSU->Externalize(ev);
- targetDraft->Externalize(ev);
-
- CATCH_ALL
- ODDisposeHandle( containerHandle );
- RERAISE;
- ENDTRY
-
- return containerHandle;
- }
-
- static void CloneIntoFlavor(Environment* ev, ODDragAndDrop* dad, ODDragItem* theDragItem,
- ODPlatformDragReference theDrag, ItemReference theItem, FlavorType theType,
- FSSpec dropFSSpec)
- {
- OSErr result;
-
- if ((result = CloneIntoFile(ev, theDragItem, dropFSSpec)) == noErr)
- {
- result = SetDragItemFlavorData(theDrag, theItem, theType, &dropFSSpec, sizeof(FSSpec), 0L);
- }
- else
- {
- dad->SetDropResult(ev, kODDropFail);
- }
- }
-
- static OSErr CloneIntoFile(Environment* ev, ODDragItem* theDragItem, FSSpec dropFSSpec)
- {
- OSErr err = noErr;
- PlatformFile file;
- file.Specify(&dropFSSpec);
-
- TRY
- ODStorageUnit* contentSU = theDragItem->fSU;
- ODID targetContentFrameID = kODNULLID;
- OSType fileType = GetStorageUnitOSType(ev,contentSU);
-
- file.Create(kODShellSignature, fileType, smSystemScript);
- SetFinderInfo(ev, contentSU, &file);
- SetIconFamily(ev, contentSU, &file);
- TempODContainer targetContainer = CreateFileContainer(ev, contentSU->GetSession(ev), &file.GetFileSpec());
- TempODDocument targetDocument = targetContainer->AcquireDocument(ev, kODDefaultDocument);
- TempODDraft targetDraft = targetDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
- TempODStorageUnit targetDraftProperties = targetDraft->AcquireDraftProperties(ev);
- TempODStorageUnit targetSU = targetDraft->CreateStorageUnit(ev);
- ODSetStrongSURefProp(ev, targetDraftProperties, kODPropRootPartSU,kODStrongStorageUnitRef, targetSU->GetID(ev));
- ODDraft* sourceDraft = contentSU->GetDraft(ev);
- ODDraftKey cloneKey = 0;
- TRY
- cloneKey = sourceDraft->BeginClone(ev, targetDraft, kODNULL, kODCloneToFile);
- sourceDraft->Clone(ev, cloneKey, contentSU->GetID(ev), targetSU->GetID(ev), 0);
- ODID contentFrameID = ODGetWeakSURefProp(ev, contentSU, kODPropContentFrame, kODWeakStorageUnitRef);
- if (contentFrameID != kODNULLID)
- {
- targetContentFrameID = sourceDraft->Clone(ev, cloneKey, contentFrameID, kODNULLID, 0);
- }
- sourceDraft->EndClone(ev, cloneKey);
- CATCH_ALL
- sourceDraft->AbortClone(ev, cloneKey);
- ENDTRY
-
- if (targetContentFrameID != kODNULLID)
- ODSetStrongSURefProp(ev, targetDraftProperties, kODPropRootFrameList, kODStrongStorageUnitRefs, targetContentFrameID);
-
- ODSURemoveProperty(ev, targetSU, kODPropMouseDownOffset);
-
- targetDraft->Externalize(ev);
-
-
- CATCH_ALL
-
- file.Delete();
- err = dragNotAcceptedErr;
- WARN("Error caught in CloneIntoFile.");
- ENDTRY
-
- return err;
- }
-
- static boolean MakeUniqueFilename( Environment *ev, ODSession* session, ODStorageUnit *su, FSSpec* spec )
- {
- const ODULong kODMaxFileNameSize = 63;
-
- Str255 prefix;
- prefix[0] = 0;
- boolean nameFromPart = false;
- TempPlatformFile file = new PlatformFile;
- file->Specify(spec);
-
- TRY
- // Get the name of the part
- if (su->Exists(ev, kODPropName, kODMacIText, 0))
- {
- ODIText* rootPartName = ODGetITextProp(ev, su, kODPropName, kODMacIText, kODNULL);
- if (rootPartName)
- {
- GetITextPString(rootPartName, prefix);
- DisposeIText(rootPartName);
- p2cstr(prefix);
- file->SetAsciiName((char*) prefix);
- nameFromPart = true;
- }
- }
-
- if (!prefix[0])
- {
- // Get the category of the part if a name cannot be found.
- ODName* categoryName = kODNULL;
- TRY
- categoryName = ODGetCatFromPartSU(ev, su, session->GetNameSpaceManager(ev));
- CATCH_ALL
- ENDTRY
- // If the above call throws, then most likely we were trying to get the category for NoPart.
- // So, set the category name for NoPart appropriately.
- if( !categoryName)
- {
- ODGetString( prefix, kODUnknownCategoryStr );
- p2cstr(prefix);
- }
- if (categoryName)
- {
- GetITextPString(categoryName, prefix);
- p2cstr(prefix);
- }
- file->SetAsciiName((char*) prefix);
- file->UniquifyName(kODNoResourceID,
- kODNULL,
- kODCategoryNumberSuffix,
- kODNULL,
- 1,
- kSpecifyNewNameOnly,
- kODForceNewName);
- ODDisposePtr(categoryName);
- nameFromPart = false;
- }
- CATCH_ALL
- ENDTRY
-
- *spec = file->GetFileSpec();
- return nameFromPart;
- }
-
- static OSType GetStorageUnitOSType( Environment *ev, ODStorageUnit *su )
- {
- OSType returnType = kODShellSignature;
-
- #if ODDebug_DragAndDrop
- ODULong numProperties = su->CountProperties(ev);
- su->Focus(ev, kODNULL, kODPosAll, kODNULL, 0, kODPosAll);
- for (ODULong i = 1; i <= numProperties; i++) {
- su->Focus(ev, kODNULL, kODPosNextSib,kODNULL,0,kODPosAll);
- ODPropertyName name = su->GetProperty(ev);
- ODDisposePtr(name);
- }
- #endif
-
- returnType = ODGetIconFilePlatformTypeFromPartSU(ev, su);
-
- /*
- //ODGetIconFilePlatformTypeFromPartSU is more correct than the below code:
-
- if (su->Exists(ev, kODPropContents,kODNULL,1)) {
- su->Focus(ev, kODPropContents,kODPosUndefined,kODNULL,1,kODPosUndefined);
- ODType suType = su->GetType(ev);
- if(suType != kODNULL) {
- ODValueNameSpace* osTypeNameSpace = (ODValueNameSpace*)
- su->GetSession(ev)->GetNameSpaceManager(ev)->HasNameSpace(ev,kODKindOldMacOSType);
- if (osTypeNameSpace) {
- ODOSType* osTypePtr;
- ODOSType osType;
- ODULong valueLen;
- ODBoolean osTypeFound = ValueNameSpaceGetEntry(
- osTypeNameSpace,
- ev,
- suType,
- (ODPtr*) &osTypePtr,
- &valueLen);
- if (osTypeFound) {
- osType = *osTypePtr;
- ODDeleteObject( osTypePtr );
-
- WASSERT(valueLen==sizeof(OSType));
- returnType = osType;
- }
- // SS: Begin Code Changes
- else {
- ODTranslation* translate = ODGetSession(ev,su)->GetTranslation(ev);
- ODOSType osType = (ODOSType)translate->GetPlatformTypeFromISOType(ev, suType);
-
- if ( osType != kODNULL )
- {
- returnType = osType;
- ((ODUByte*)(&returnType))[0] = kODPlatformKindFileChar1;
- }
- }
- // SS: End Code Changes
- }
- }
- }
- */
- return returnType;
- }
-
-
- static OSErr CopyToDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODDragItem* theDragItem)
- {
- const ODULong kCopyBlockSize = 512;
- OSErr result = noErr;
- ODPtr dataPtr = ODNewPtr(kCopyBlockSize);
- ODULong dataSize = theDragItem->fSU->GetSize(ev);
-
- ODULong currentByte = 0;
- while ((currentByte < dataSize) && (result == noErr)) {
- ODULong bytesRead = StorageUnitGetValue(theDragItem->fSU, ev, kCopyBlockSize, dataPtr);
- result = SetDragItemFlavorData(theDrag, theItem, theType, dataPtr, bytesRead, currentByte);
- WASSERTM(result == noErr, "Error from SetDragItemFlavorData in CopyToDragItemInChunks.");
- currentByte += bytesRead;
- }
- ODDisposePtr(dataPtr);
- WASSERTM(currentByte == dataSize, "Bytes written is NOT equal to dataSize.");
-
- return result;
- }
-
- static OSErr CopyFromDragItemInChunks(Environment* ev,
- FlavorType theType,
- ItemReference theItem,
- ODPlatformDragReference theDrag,
- ODStorageUnitView* destSUView)
- {
- const ODULong kCopyBlockSize = 512;
- OSErr result = noErr;
- ODPtr dataPtr = ODNewPtr(kCopyBlockSize);
- long dataSize = 0;
- ODULong totalRead = 0;
- ODULong oldValueSize = destSUView->GetSize(ev);
-
- result = GetFlavorDataSize(theDrag, theItem, theType, &dataSize);
- while ((totalRead < dataSize) && (result == noErr)) {
- Size bytesRead = dataSize - totalRead;
- if (bytesRead > kCopyBlockSize)
- bytesRead = kCopyBlockSize;
- result = GetFlavorData(theDrag, theItem, theType, dataPtr, &bytesRead, totalRead);
- WASSERTM(result == noErr, "Error from GetFlavorData in CopyFromDragItemInChunks.");
- StorageUnitViewSetValue(destSUView, ev, bytesRead, dataPtr);
- totalRead += bytesRead;
- }
- ODDisposePtr(dataPtr);
-
- ODULong newValueSize = destSUView->GetOffset(ev);
- if (oldValueSize > newValueSize)
- destSUView->DeleteValue(ev, oldValueSize - newValueSize);
-
- return result;
- }
-
-
- #ifdef ODDebug_DragAndDrop
- void PrintDragReference(ODPlatformDragReference dragRef, char* header)
- {
- unsigned short items = 0;
- CountDragItems(dragRef, &items);
- somPrintf("%s: fDragReference %x numItems %d\n", header, dragRef, items);
- for (unsigned short i = 1; i <= items; i++) {
- ItemReference itemRef;
- GetDragItemReferenceNumber(dragRef, i, &itemRef);
- unsigned short numFlavors = 0;
- CountDragItemFlavors(dragRef, itemRef, &numFlavors);
- FlavorType theType;
- Size dataSize = 0;
- for (unsigned short j = 1; j <= numFlavors; j++) {
- GetFlavorType (dragRef, itemRef, j, &theType);
- GetFlavorDataSize(dragRef, itemRef, theType, &dataSize);
- somPrintf("%s: itemRef %x item %d flavor %d size %d type ", header, itemRef, i, j, dataSize);
- for (short k = 0; k <= 3; k++) {
- somPrintf("%c", ((char*) &theType)[k]);
- }
- somPrintf("\n");
- if ((theType == 'hfs ') && (dataSize > 0)) {
- HFSFlavor hfsFlavor;
- GetFlavorData(dragRef,itemRef,theType,&hfsFlavor,&dataSize,0);
- somPrintf("type %x creator %x name %s\n", hfsFlavor.fileType, hfsFlavor.fileCreator, p2cstr(hfsFlavor.fileSpec.name));
- }
- }
- }
- }
-
- void PrintStorageUnit(Environment* ev, ODStorageUnit* su, char* header)
- {
- ODStorageUnitCursor* cursor = su->CreateCursorWithFocus(ev);
-
- ODULong numProperties = su->CountProperties(ev);
- su->Focus(ev, kODPropContents, kODPosUndefined, kODNULL, 0, kODPosUndefined);
- ODULong numValues = su->CountValues(ev);
- somPrintf("%s: su %x numProperties %d numContentValues %d\n", header, su, numProperties, numValues);
- for (short i = 1; i <= numValues; i++) {
- su->Focus(ev, kODNULL, kODPosSame, kODNULL, i, kODPosUndefined);
- ODValueType type = su->GetType(ev);
- somPrintf("%s: Type %d %s\n", header, i, type);
- ODDisposePtr(type);
- }
-
- su->FocusWithCursor(ev, cursor);
- delete cursor;
- }
-
- #endif
-
- SOM_Scope OSErr SOMLINK ODDragAndDropEnterHandler(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropEnterHandler");
-
- #if ODDebug_DragAndDrop
- somPrintf("In EnterHandler.\n");
- #endif
-
- OSErr returnCode = noErr;
-
- ODVolatile(returnCode);
- SOM_TRY
- OSErr result = noErr;
- ODDragLink* newLink = kODNULL;
- ODUShort items = 0;
-
- CountDragItems(theDrag, &items);
- for (ODUShort i = 1; i <= items; ++i)
- {
- ItemReference itemID;
- FlavorFlags theFlags;
- GetDragItemReferenceNumber(theDrag, i, &itemID);
- result = GetFlavorFlags(theDrag, itemID, kODPromiseFlavor, &theFlags);
- if (result == noErr) {
- if (_fDragReference != theDrag)
- {
- _fListFromHandler = kODTrue;
- newLink = new ODDragLink((ODDragItem*)itemID, kODFalse);
- _fDragItemList->AddLast((Link*)newLink);
- }
- }
- else if (result == badDragFlavorErr) {
- ODStorageSystem* storage = _fStorageSystem;
- ODTranslation* translate = _fSession->GetTranslation(ev);
- ODDragItem* newItem = kODNULL; ODVolatile(newItem);
-
- ODUShort count;
- ODUShort j = 1;
- HFSFlavor hfsFlavor;
- PlatformFile* finderFile = kODNULL;
- CountDragItemFlavors(theDrag, itemID, &count);
- for (j = 1; (j <= count) && (newItem == kODNULL); j++) {
- OSType theType;
- OSErr err = GetFlavorType(theDrag, itemID, j, &theType);
- if ((err == noErr) && (theType == flavorTypeHFS)) {
- Size dataSize = sizeof(HFSFlavor);
- OSErr err = GetFlavorData(theDrag, itemID, theType, &hfsFlavor, (Size*) &dataSize, 0);
- if (err == noErr)
- {
- FSSpec targetFileSpec = hfsFlavor.fileSpec;
- if ((hfsFlavor.fileCreator == kODShellSignature) &&
- IsOpenDocDocument(hfsFlavor.fileType))
- {
- ODBoolean wasAliased;
- ODBoolean targetIsFolder;
- OSErr err = ResolveAliasFile(&targetFileSpec, TRUE, &targetIsFolder, &wasAliased);
- if ((err == noErr) && (!targetIsFolder)) {
- FInfo finderInfo;
- err = FSpGetFInfo(&targetFileSpec, &finderInfo);
- if ((err == noErr) && IsOpenDocDocument(finderInfo.fdType)) {
- ODByteArray* ba = CreateByteArray(&targetFileSpec, sizeof(FSSpec));
- TRY
- newItem = new(ODGetDefaultHeap()) ODFileDragItem(storage, kODTrue);
- ((ODFileDragItem*) newItem)->Initialize(ev, ba);
- CATCH_ALL
- delete newItem;
- newItem = kODNULL;
- ENDTRY
- DisposeByteArray(ba);
- }
- }
- }
- finderFile = new PlatformFile();
- finderFile->Specify(&targetFileSpec);
- }
- }
- if( theType == kODBentoFlavor )
- {
- ODHandle tempHandle;
- ODVolatile( tempHandle );
- TRY
- Size theSize;
- OSErr err = GetFlavorDataSize( theDrag, itemID, theType, &theSize );
- tempHandle = ODNewHandle( theSize );
- ODLockHandle( tempHandle );
- err = GetFlavorData(theDrag, itemID, theType, *tempHandle, (Size*) &theSize, 0);
- ODUnlockHandle(tempHandle);
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(storage, tempHandle, kODTrue);
- ((ODMemDragItem*) newItem)->Open(ev);
- CATCH_ALL
- if( newItem )
- {
- ODDeleteObject( newItem );
- }
- else
- {
- ODDisposeHandle( tempHandle );
- }
-
- ENDTRY
- }
- }
- if (newItem == kODNULL) {
- newItem = new(ODGetDefaultHeap()) ODMemDragItem(storage, kODTrue);
- ((ODMemDragItem*) newItem)->Initialize(ev);
- }
- ODStorageUnit* su = newItem->fSU;
- if (finderFile)
- {
- GetFinderInfo(ev, su, finderFile);
- GetIconFamilyFromFile(ev, su, finderFile);
- delete finderFile;
- }
- ODSUForceFocus(ev, su, kODPropContents, kODNULL);
- for (j = 1; j <= count; j++) {
- OSType theType;
- OSErr err = GetFlavorType(theDrag, itemID, j, &theType);
- ODValueType isoType = translate->GetISOTypeFromPlatformType(ev, theType, kODPlatformDataType);
- su->Focus(ev, kODPropContents, kODPosUndefined, kODNULL, 0, kODPosUndefined);
- StorageUnitSetPromiseValue(su, ev, isoType, 0, sizeof(ItemReference), &itemID, kODNULL);
- ODDisposePtr(isoType);
- // If theType is 'styl', add a promise for 'stxt'
- if ( theType == kODScrapTypestyl )
- {
- if ( DragItemHasFlavor(theDrag, itemID, kODScrapTypeTEXT) && !DragItemHasFlavor(theDrag, itemID, kODScrapTypestxt) )
- StorageUnitSetPromiseValue(su, ev, kODApplestxt, 0, sizeof(ItemReference), &itemID, kODNULL);
- }
- else if (theType == flavorTypeHFS)
- {
- ODValueType isoType = translate->GetISOTypeFromPlatformType(ev, hfsFlavor.fileType, kODPlatformFileType);
- su->AddValue(ev, isoType);
- ODDisposePtr(isoType);
- }
- }
- _fListFromHandler = kODTrue;
- newLink = new ODDragLink(newItem, kODTrue);
- _fDragItemList->AddLast((Link*)newLink);
- }
- else
- {
- WASSERTM(result == noErr, "Error from GetFlavorFlags in tracking handler");
- returnCode = result;
- break;
- }
- }
- _fDragReference = theDrag;
- _fAttributes = 0;
- if (_fListFromHandler)
- {
- LinkedListIterator* newIter = new LinkedListIterator(_fDragItemList);
- ODDragItemIterator* tmpIter = new ODDragItemIterator();
- THROW_IF_NULL(tmpIter, kODErrOutOfMemory);
- tmpIter->InitDragItemIterator(ev, newIter);
- _fDragItemIterator = tmpIter;
- }
-
- ODDeleteObject(_fFacetsRejected);
-
- SOM_CATCH_ALL
-
- returnCode = ErrorCode();
- ODDeleteObject(_fFacetsRejected);
- if (_fDragItemList)
- _fDragItemList->DeleteAllLinks();
-
- SOM_ENDTRY
-
- _fFacetsRejected = new OpenHashTable(OpenHashTable::StdEqual, OpenHashTable::StdHash, kODNULL);
- _fFacetsRejected->Initialize(kODInitialNumEntries,
- sizeof(ODFacet*),
- sizeof(ODFacet*));
-
- return returnCode;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropEnterWindow(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag,
- ODPlatformWindow theWindow)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropEnterWindow");
-
- // This is a private method called only from MyDragTrackingHandler.
- // It can do without its own SOM_TRY.
-
- #if ODDebug_DragAndDrop
- somPrintf("Enter EnterWindow.\n");
- #endif
-
- ODPoint mouse, localMouse;
- Point qdMouse;
- ODFacet* targetFacet = kODNULL;
- ODBoolean handled = kODFalse;
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
- if (!targetFacet)
- _fAttributes &= kODDragHasLeftSourcePartMask;
- else
- {
- while (targetFacet && !handled)
- {
- if ((targetFacet->GetFrame(ev) == _fSourceFrame) && (_fHasLeftSourceFrame == kODFalse)) {
- _fAttributes |= kODDragIsInSourcePart;
- _fAttributes |= kODDragIsInSourceFrame;
- }
- else
- {
- _fHasLeftSourceFrame = kODTrue;
- ODPart* targetPart = targetFacet->GetFrame(ev)->AcquirePart(ev);
- if (targetPart == _fSourcePart)
- _fAttributes = kODDragIsInSourcePart;
- else {
- _fHasLeftSourcePart = kODTrue;
- _fAttributes = 0;
- }
- ODReleaseObject(ev, targetPart);
- }
- handled = targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- if (!handled)
- {
- _fFacetsRejected->ReplaceEntry(&targetFacet, &targetFacet);
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
- }
- }
- }
- _fPrevFacet = targetFacet;
-
- return noErr;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropInWindow(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag,
- ODPlatformWindow theWindow)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropInWindow");
-
- ODPoint mouse, localMouse;
- Point qdMouse;
- ODFacet* targetFacet = kODNULL;
- ODBoolean handled = kODFalse;
-
- SOM_TRY
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- // Get the facet under the current mouse location.
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- // We are leaving the window, call DragLeave on the last facet and return
- if (!targetFacet) {
- _fAttributes &= kODDragHasLeftSourcePartMask;
- if (_fPrevFacet) {
- _fPrevFacet->DragLeave(ev, &localMouse, kODNULL);
- }
- }
- // Otherwise, the mouse is still in the OpenDoc window.
- else
- {
- // Since the mouse is still in the OpenDoc window, we want to implement the following protocal for
- // having different facets draw drag highlighting. Everytime the mouse moves and is still in the window:
- // A. If the mouse enters a new facet, call DragEnter on the new one.
- // 1. If the new facet can't accept the drag, call DragEnter on the next containg facet.
- // B. If the mouse stays within the same facet, call DragWithin on that facet again.
- // C. If the mouse leaves a facet, call DragLeave on the facet.
- // We don't want drag-highlighiting to take place on the frame that originates the drag,
- // unless the mouse leaves the frame, then enters it again. So, we do the following:
- // 1. Store a refernce to the frame that originated the drag..
- // 2. Define a boolean that signifies that the mouse has not left the source frame.
- // 3. While the mouse is still in the source frame, tell the part not to do any drag-hiliting as above.
- // 4. When the mouse leaves the source frame, set the boolean that signifies we have not left the source
- // to false. This tells subsequent parts to do hilighting following the above algorithm.
-
- // We basically want to do one of the following in this loop:
- // 1. Track that the mouse has entered a new facet and call DragEnter on it.
- // 2. Track that the mouse has left a facet and call DragLeave on it.
- // 3. Track that the mouse is still in a facet and call DragWithin on it.
- // Obviously there are special cases to all of the above. See the source comments below for more info.
- while (targetFacet && !handled)
- {
- // Check whether we are still in the source frame, and haven't ever left it. If so, no hiliting needed.
- if ((targetFacet->GetFrame(ev) == _fSourceFrame) && (_fHasLeftSourceFrame == kODFalse)) {
- _fAttributes |= kODDragIsInSourcePart;
- _fAttributes |= kODDragIsInSourceFrame;
- }
- // Otherwise, we are either in a new frame, or we have left and reenter the source frame.
- // Tell the part to start doing hiliting.
- else {
- _fHasLeftSourceFrame = kODTrue;
- ODPart* targetPart = targetFacet->GetFrame(ev)->AcquirePart(ev);
- if (targetPart == _fSourcePart)
- _fAttributes = kODDragIsInSourcePart;
- else {
- _fHasLeftSourcePart = kODTrue;
- _fAttributes = 0;
- }
- ODReleaseObject(ev, targetPart);
- }
- if (_fPrevFacet == targetFacet) {
- handled = targetFacet->DragWithin(ev, &localMouse, _fDragItemIterator, kODNULL);
- }
- else {
- // We need to call DragLeave on the previous facet before we call DragEnter on the new one, even
- // though the DragEnter can return false. Why not call DragEnter first, decide if it succeeds, then
- // call DragLeave? Because of ShowDragHilite and HideDragHilite Drag Manager functions need this
- // order or drag hiliting is messed up.
- if( _fPrevFacet )
- _fPrevFacet->DragLeave(ev, &localMouse, kODNULL);
- handled = targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- // if ( _fPrevFacet && !handled ) {
- // targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- // }
- }
- if (!handled)
- {
- // If any facet rejects a particular drag, then at no time during the current will it ever
- // accept it again. A part can only handle certain drag kinds, and that will not change during
- // a drag. So, if a drag is rejected, keep a list of facets that have rejected the current
- // drag and don't try to do hiliting for them again for this drag.
- _fFacetsRejected->ReplaceEntry(&targetFacet, &targetFacet);
- // On of the following happened previous to this statement:
- // DragWithin or DragEnter was called on a facet and the part returned false.
- // So, give the container a crack at the drag.
- targetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
- if( targetFacet )
- targetFacet->DragEnter(ev, &localMouse, _fDragItemIterator, kODNULL);
- // else the root rejected the drag and there is no container to take the drag. Will just
- // exit this loop.
- }
- }
- }
- _fPrevFacet = targetFacet;
-
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- return noErr;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropLeaveWindow(ODDragAndDrop *somSelf, Environment *ev,
- ODPlatformDragReference theDrag,
- ODPlatformWindow theWindow)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropLeaveWindow");
-
- #if ODDebug_DragAndDrop
- somPrintf("In LeaveWindow.\n");
- #endif
-
- SOM_TRY
- ODPoint mouse, localMouse;
- Point qdMouse;
-
- GetDragMouse(theDrag, &qdMouse, 0L);
- mouse = qdMouse;
- ODFacet* dummyTargetFacet = somSelf->FindTargetFacet(ev, theWindow, &mouse, &localMouse);
-
- _fAttributes = 0;
- if (_fPrevFacet) {
- _fPrevFacet->DragLeave(ev, &localMouse, kODNULL);
- _fPrevFacet = kODNULL;
- }
- SOM_CATCH_ALL
- ENDTRY
-
- _fHasLeftSourceFrame = kODTrue;
- _fHasLeftSourcePart = kODTrue;
-
- return noErr;
- }
-
- SOM_Scope OSErr SOMLINK ODDragAndDropLeaveHandler(ODDragAndDrop *somSelf, Environment *ev)
- {
- ODDragAndDropData *somThis = ODDragAndDropGetData(somSelf);
- ODDragAndDropMethodDebug("ODDragAndDrop","ODDragAndDropLeaveHandler");
-
- #if ODDebug_DragAndDrop
- somPrintf("In LeaveHandler.\n");
- #endif
-
- // Now undo the damage done in the dragTrackingEnterHandler section.
- // NOTE: It is OK to blow away the drag items here because at this point
- // the drop handler will already have processed the drop if any.
- if (_fListFromHandler)
- {
- TRY{
- somSelf->Clear(ev);
- }CATCH_ALL{
- // ignore error
- }ENDTRY
- _fListFromHandler = kODFalse;
- _fDragReference = 0;
- }
- _fAttributes = 0;
-
- return noErr;
- }
-
- static void SetIconFamily(Environment* ev, ODStorageUnit* fromSU, PlatformFile* file)
- {
- static const ResType kIconType[6] = {'ICN#','icl4','icl8','ics#','ics4','ics8'};
- static const short kIconSize[6] = {256, 512, 1024, 64, 128, 256 };
- ODIconFamily icons = ODGetIconFamilyProp(ev, fromSU, kODPropCustomIcon, kODIconFamily, kAllIconsMask);
-
- if (icons)
- {
- // write icons to the file
- long i = 6;
- do {
- Handle icon;
- char state;
- if ((GetIconFromSuite(&icon, icons, kIconType[--i]) == noErr) && (icon != nil))
- {
- state = HGetState(icon);
- HLock(icon);
- WASSERT(GetHandleSize(icon) == kIconSize[i]);
- file->WriteResourcePtr(kIconType[i], kCustomIconResource, *icon, kIconSize[i]);
- HSetState(icon, state);
- }
- } while (i);
- file->SetCustomIcon(kODTrue);
- }
- }
-
- static void SetFinderInfo(Environment* ev, ODStorageUnit* su, PlatformFile* file)
- {
- InitDateInfo(ev, su);
- ODULong modDate = ODGetModificationDate(ev, su);
- ODULong creationDate = ODGetCreationDate(ev, su);
-
- file->CreateResFile();
- file->SetFileModDate(modDate);
- file->SetFileCreationDate(creationDate);
- file->SetStationery(ODGetSUIsStationery(ev, su));
- }
-
- static OSErr GetDropFSSpec(ODPlatformDragReference theDrag, FSSpec &dropFSSpec)
- {
- AEDesc dropDescriptor;
-
- OSErr result = GetDropLocation(theDrag, &dropDescriptor);
- if ((result != noErr) ||
- (dropDescriptor.descriptorType == typeNull) ||
- (dropDescriptor.dataHandle == nil))
- {
- result = fnfErr; // Can't create a file unless we know where it goes!
- }
- else
- {
- AEDesc fssDescriptor;
- result = AECoerceDesc(&dropDescriptor, typeFSS, &fssDescriptor);
- AEDisposeDesc(&dropDescriptor);
- if (result == noErr) {
- ODBlockMove(*fssDescriptor.dataHandle, &dropFSSpec, sizeof(FSSpec));
- AEDisposeDesc(&fssDescriptor);
-
- // Use PBGetCatInfo to get the directoryID of the target directory.
- CInfoPBRec getInfoPB;
- getInfoPB.dirInfo.ioCompletion = 0L;
- getInfoPB.dirInfo.ioNamePtr = (StringPtr) &(dropFSSpec.name);
- getInfoPB.dirInfo.ioVRefNum = dropFSSpec.vRefNum;
- getInfoPB.dirInfo.ioFDirIndex = 0;
- getInfoPB.dirInfo.ioDrDirID = dropFSSpec.parID;
- result = PBGetCatInfoSync(&getInfoPB);
- if (result == noErr)
- {
- dropFSSpec.parID = getInfoPB.dirInfo.ioDrDirID;
- dropFSSpec.name[0] = 0;
- }
- }
- }
-
- return result;
- }
-
- static boolean IsTrashFolder(FSSpec dropFSSpec)
- {
- short trashVol;
- long trashDir;
-
- return (FindFolder(dropFSSpec.vRefNum,kTrashFolderType,kDontCreateFolder,&trashVol,&trashDir) == noErr) &&
- (trashVol==dropFSSpec.vRefNum) && (
- (trashDir==dropFSSpec.parID) );
-
- }
-
- static boolean IsFrontProcess()
- {
- ProcessSerialNumber myProcess, frontProcess;
- boolean inFront = false;
-
- GetCurrentProcess(&myProcess);
- GetFrontProcess(&frontProcess);
- SameProcess(&myProcess, &frontProcess, &inFront);
-
- return inFront;
- }
-
- static OSErr CreateReplaceFileEvent(Environment* ev,
- AppleEvent* replaceFileEvent,
- ODSession* session,
- ProcessSerialNumber* psn)
- {
- OSErr err = noErr;
- AEAddressDesc targetAddress;
- TempAEDesc tempTargetAddress = kODNULL;
-
- err = AECreateDesc(typeProcessSerialNumber, psn, sizeof(ProcessSerialNumber), &targetAddress);
-
- if (err == noErr)
- {
- err = AECreateAppleEvent(kODShellSignature, kODReplaceFileEventID,
- &targetAddress, kAutoGenerateReturnID,
- kAnyTransactionID, replaceFileEvent);
- AEDisposeDesc(&targetAddress);
- }
- if ( err == noErr )
- err = AEPutParamPtr(replaceFileEvent, kODSession, typeLongInteger,
- &session, sizeof(ODSession*));
- return err;
- }
-
- static OSErr SetupReplaceFileEvent(Environment* ev,
- AppleEvent* replaceFileEvent,
- FSSpec* sourceFileSpec,
- FSSpec* destFileSpec)
- {
- OSErr err = noErr;
- if (err == noErr)
- {
- err = AEPutParamPtr(replaceFileEvent, kODSourceFileSpec, typeFSS,
- sourceFileSpec, sizeof(FSSpec));
- }
- if ( err == noErr )
- err = AEPutParamPtr(replaceFileEvent, kODDestinationFileSpec, typeFSS,
- destFileSpec, sizeof(FSSpec));
-
- #ifdef ODDebug
- if (err != noErr)
- {
- WARN("Error in SetupReplaceFileEvent: %d", err);
- }
- #endif
-
- return err;
- }
-
- static OSErr SendReplaceFileEvent(AppleEvent* replaceFileEvent, ProcessSerialNumber* psn)
- {
- OSErr err;
- AppleEvent replyAppleEvent;
-
- SetFrontProcess(psn);
-
- // TempAEDesc tmpReplaceFileAppleEvent(replaceFileEvent);
- err = AESend(replaceFileEvent, &replyAppleEvent, kAENoReply | kAEInteractWithSelf,
- kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
-
- #ifdef ODDebug
- if (err != noErr)
- {
- WARN("Error in SendReplaceFileEvent: %d", err);
- }
- #endif
-
- return err;
- }
-
- static OSErr DisposeReplaceFileEvent(AppleEvent* replaceFileEvent)
- {
- return AEDisposeDesc(replaceFileEvent);
- }
-
- static OSErr ODPascal ReplaceFileAEHandler(
- const AppleEvent* replaceFileEvent,
- AppleEvent* reply,
- long refCon)
- {
- OSErr err = noErr;
- DescType returnedType;
- Size actualSize;
- FSSpec sourceFileSpec;
- FSSpec destFileSpec;
- ODSession* session = kODNULL;
-
- err = AEGetParamPtr(replaceFileEvent, kODSession,
- typeLongInteger, &returnedType,
- &session, sizeof(ODSession*), &actualSize);
- WASSERTM(actualSize == sizeof(ODSession*), "Incorrect kODSession size");
-
- if (err == noErr)
- {
- err = AEGetParamPtr(replaceFileEvent, kODDestinationFileSpec,
- typeFSS, &returnedType,
- &destFileSpec, sizeof(FSSpec), &actualSize);
- WASSERTM(actualSize == sizeof(FSSpec), "Incorrect DestinationFileSpec size");
- }
-
- if (err == noErr)
- {
- Environment* ev = somGetGlobalEnvironment();
- ParamText(destFileSpec.name, "\p", "\p", "\p");
- err = AEInteractWithUser(kAEDefaultTimeout, NULL, NULL);
- if ((err == noErr) && ODAskUserReplace(ev, session))
- {
- err = AEGetParamPtr(replaceFileEvent, kODSourceFileSpec,
- typeFSS, &returnedType,
- &sourceFileSpec, sizeof(FSSpec), &actualSize);
- if (err == noErr)
- {
- WASSERTM(actualSize == sizeof(FSSpec), "Incorrect kODSourceFileSpec size");
- TempPlatformFile sourceFile = new PlatformFile;
- sourceFile->Specify(&sourceFileSpec);
- TempPlatformFile destFile = new PlatformFile;
- destFile->Specify(&destFileSpec);
-
- destFile->MoveToTrash();
- sourceFile->Move(destFileSpec.parID);
- }
- }
- }
-
- #ifdef ODDebug
- if (err != noErr)
- WARN("Error occured in ReplaceFileAEHandler: %d", err);
- #endif
-
- return err;
- }
-
- static void RespecifyToTempFolder(PlatformFile* file)
- {
- ODSLong tempDirID;
- FSSpec fsSpec = file->GetFileSpec();
-
- THROW_IF_ERROR(FindFolder(fsSpec.vRefNum, kTemporaryFolderType, kCreateFolder,
- &(fsSpec.vRefNum), &tempDirID));
- fsSpec.parID = tempDirID;
- file->Specify(&fsSpec);
- if (file->Exists())
- file->Delete();
- }
-
-